2019年鐵人賽
拜讀到這篇我知道你懂 hoisting,可是你了解到多深?
,精闢的解釋又了解更多對 hoisting 的觀念,藉著這篇的分析邏輯做一下筆記。
下面這段程式會出錯,是因為第一行 a 尚未被宣告,代表找不到記憶體位置
console.log(a); //Uncaught ReferenceError: a is not defined
但為何這段程式卻顯示 undefined 呢?
console.log(a); //undefined
var a = 2;
因為 a 被提升到 log 前宣告了!
JS 對 var 會做兩個動作
//範例1
console.log(a); //undefined
var a = 2;
//把範例1想像成下面執行過程
var a; //宣告提升
console.log(a); //undefined
a = 2; //賦值
//範例2
var b = 10;
var b;
console.log(b); //10,不要以為 b 重新賦值為 undefined
//把範例2想像成下面執行過程
var b; //宣告提升
var b;
b = 10;
console.log(b); //10
console.log(x); //f x(){}
var x = 1;
function x(){}
本來以為不會有 hoisting
console.log(a); //Uncaught ReferenceError: a is not defined
let a = 2;
直到看到文章提的範例
var a = 10;
function test(){
console.log(a);
let a;
}
test();
我以為 log 結果是 10 ,會找全域變數的 a
居然是Uncaught ReferenceError: a is not defined
Uncaught ReferenceError: a is not defined
Uncaught ReferenceError: a is not defined
表示說 let 的確有被 hoisting,只是給的反應與 var 不同
回頭看看 var,var 在提升後會給初始值 undefined,所以 log 才會是undefined
//範例
console.log(a); //undefined
var a = 1;
//把範例想像成下面執行過程
var a; //提升後會給初始值 undefined
console.log(a); //undefined
a = 1;
let 與 const 在「提升後」,和「賦值之前」,存在一個區間叫 Temporal Dead Zone (TDZ),在「賦值之前」存取它就會拋出錯誤。
//範例
console.log(a); //undefined
let a = 1;
//把範例想像成下面執行過程
let a; //提升後不會給初始值 undefined,也是 TDZ 的開始
console.log(a); //Uncaught ReferenceError: a is not defined,因為在賦值之前,所以拋出錯誤